<?php
// Check for MySQL Support as some newb may not have checked for it or installed it :P
if (!function_exists('mysql_connect')) die('Sorry, your server does not have support for MySQL');

## DATABASE CLASS ##############################################################
class MySQL extends Database {

	var $query_num = 0; // Amount of queries processed
	var $query_time = 0; // Amount of time taken to process a query
	var $total_query_time = 0; // Total amount of time taken to process the queries
	var $sql; // A copy of the query we are using or building
	var $query_debug; // The query info used for the debug

	############################################################################
	## CONSTRUCTOR                                                            ##
	############################################################################
	function MySQL() {
		Base::getThis();

		// Setup table and connection variables
		require_once('includes/database/tables.inc');

		// Ensure loading of micro_time function
		$this->load->helper('date');
	}

	############################################################################
	## DATABASE METHODS                                                       ##
	############################################################################

	#### CONNECT ###############################################################
	function connect($host, $username, $password, $name) {
		$db_connection = mysql_connect($host, $username, $password) or die('Fatal Error: Unable to connect to database server<br />MySQL Reported: '.mysql_error());
		mysql_select_db($name) or die('Fatal Error: Unable to connect to database<br />MySQL Reported: '.mysql_error());
		return $db_connection;
	}

	#### QUERY #################################################################
	function query($query = FALSE, $database = FALSE) {

		// Choose the correct database
		if (!$database) {
			if (isset($this->current_table)) {
				$table = explode('.', $this->current_table);
				if (isset($table[1])) $table = $table[1];
				else $table = $table[0];
				if (isset($this->connection[$table])) $database = $this->connection[$table];
				else $database = $this->db_connection[1]; // Failsafe
			}
			else $database = $this->db_connection[1]; // Failsafe
		}

		// Used for the sql_error() function
		$this->last_connection = $database;

		// If no query is supplied try and get one that may have been built with
		// shortcut methods
		if (!$query) $query = $this->sql;

		// Lets keep a copy of this query for the sql_error() function
		$this->last_query = $query;

		// Make sure we run the debug things below on the first run to catch it
		// as the debug status will not have been pulled from the database yet
		if (!isset($this->config['debug_enabled'])) $this->config['debug_enabled'] = TRUE;

		// Either time the query and run the debug function or don't
		if ($this->config['debug_enabled']) {
			// Ready... Set... Go!
			$start_time = micro_time();

			// Do the deed!
			$result = mysql_query($query, $database);

			// How long did the query take?
			$query_time = (micro_time() - $start_time);

			// How long so far?
			$this->total_query_time += $query_time;

			// Let's get some information about this beast
			$this->debug($query, $query_time, $database);
		} else {
			// Do the deed!
			$result = mysql_query($query, $database);
		}

		// Add one to the query count
		$this->query_num++;

		// Reset these now that we have used them
		$this->current_table = NULL;
		$this->sql = NULL;
		$this->where = NULL;
		$this->order = NULL;
		$this->result =& $result;

		return $result;
	}

	#### FETCH ARRAY ###########################################################
	function fetchArray($result = FALSE, $type = MYSQL_ASSOC) {
		if (!$result) $result = $this->result;
		$result = mysql_fetch_array($result, $type);
		return $result;
	}

	#### FETCH ROW #############################################################
	function fetchRow($result = FALSE) {
		if (!$result) $result = $this->result;
		$result = mysql_fetch_row($result);
		return $result;
	}

	#### NUM ROWS ##############################################################
	function numRows($result = FALSE) {
		if (!$result) $result = $this->result;
		$result = mysql_num_rows($result);
		return $result;
	}

	#### DEBUG #################################################################
	// Add to debug array
	function debug($query, $query_time, $connection = FALSE) {

		if (!$connection) $connection = $db_connection[1];

		// MySQL can't explain UPDATE, DELETE, INSERT, TRUNCATE etc...
		if (eregi('SELECT', substr($query, 0, 6))) {
			$data = @mysql_fetch_array(mysql_query('EXPLAIN '.$query, $connection), MYSQL_ASSOC);
		} else {
			$data = array(mysql_query('EXPLAIN '.$query, $connection));
		}
		$data['query_time'] = $query_time;
		$data['query'] = $query;
		$this->query_debug[] = $data;
	}

	#### RESULT ################################################################
	// Grab the result and return it
	function result($field_as_array_key = FALSE, $result = FALSE) {

		if (!$result) $result = $this->result;
		$type = ($field_as_array_key ? MYSQL_BOTH : MYSQL_ASSOC);

		// Put our result rows into an array ready to be returned to a foreach
		$rows = array();
		while ($row = $this->fetchArray($result, $type)) {
			if (is_string($field_as_array_key)) $rows[$row[$field_as_array_key]] = $row;
			else if ($field_as_array_key) $rows[$row[0]] = $row;
			else $rows[] = $row;
		}

		return $rows;
	}

	#### CLOSE #################################################################
	// Close connection
	function close() {
		mysql_close();
	}

	############################################################################
	## SHORTCUT METHODS                                                       ##
	############################################################################

	#### INSERT ID #############################################################
	// Get the ID generated from the previous query
	function insertId($connection = FALSE) {
		global $db_connection;

		// Try and grab the last_connection
		if (!$connection) $connection = $this->last_connection;

		// Still nothing? Best use the LF conneciton
		if (!$connection) $connection = $this->db_connection[1];

		return @mysql_insert_id($connection);
	}

	#### AFFECTED ROWS #########################################################
	// Get the number of affected rows from the previous query
	function affectedRows() {
		return @mysql_affected_rows($this->conn_id);
	}

	#### SELECT ################################################################
	// A quick method for SELECT queries
	function select($table_array, $field_array = NULL) {

		if (is_array($table_array)) { $table = implode(' JOIN ', $table_array); $this->current_table = $table_array[0]; }
		else { $table = $table_array; $this->current_table = $table_array; }

		if (is_array($field_array)) $fields = implode(', ', $field_array);
		else if ($field_array != NULL) $fields = $field_array;
		else $fields = '*';

		$sql = 'SELECT '.$fields.' FROM '.$table;
		$this->sql .= $sql;

		return $sql;
	}


	#### INSERT ################################################################
	// A quick method for INSERT queries
	function insert($table, $field_value_array, $force_null_vars = FALSE) {

		$this->current_table = $table;

		$fields = array();
		$values = array();

		foreach($field_value_array as $field => $value) {
			// Ignore exact NULL field values as these will have been purposlely set by a script
			// to be excuded from the SQL. Also, ignore the "submit" post element automatically
			// returned by forms
			if (($value !== NULL || $force_null_vars) && $field != 'submit') {
				$fields[] = $field;
				if ($value === NULL) $values[] = "NULL";
				else $values[] = "'".$value."'";
			}
		}

		$sql = "INSERT INTO ".$table." (".implode(', ', $fields).") VALUES (".implode(', ', $values).")";
		$this->sql .= $sql;

		return $sql;
	}

	#### UPDATE ################################################################
	// A quick method for UPDATE queries
	function update($table, $field_value_array, $force_null_vars = FALSE) {

		$this->current_table = $table;

		$fields = array();
		$values = array();

		foreach($field_value_array as $field => $value) {
			// Ignore exact NULL post variables as these will have been purposlely set by a script
			// to be excuded from the SQL. Also, ignore the "submit" post variable automatically
			// returned by forms
			if (($value !== NULL || $force_null_vars) && $field != 'submit') {
				if (strstr($field, '*')) $values[] = str_replace('*', '', $field)." = ".$value;
				else if ($value === NULL) $values[] = $field." = NULL";
				else $values[] = $field." = '".$value."'";
			}
		}

		$sql = "UPDATE ".$table." SET ".implode(', ', $values);
		$this->sql .= $sql;

		return $sql;
	}

	#### DELETE ################################################################
	// A quick method for DELETE queries
	function delete($table, $limit = FALSE) {

		$this->current_table = $table;
		$sql = "DELETE FROM ".$table;

		$this->sql .= $sql;
		return $sql;
	}

	#### WHERE #################################################################
	// A quick method for appending WHERE conditions
	function where($condition, $operator = 'AND') {
		if ($condition) {

			if (isset($this->where)) $sql = ' '.$operator.' '.$condition;
			else $sql = ' WHERE '.$condition;

			$this->where = TRUE;
			$this->sql .= $sql;
			return $sql;
		}
	}

	#### LIMIT #################################################################
	// A quick method for appending LIMIT conditions
	function limit($condition) {
		if ($condition) {

			if (is_array($condition))
				$sql = " LIMIT ".$condition[0].", ".$condition[1];
			else
				$sql = " LIMIT ".$condition;

			$this->sql .= $sql;
			return $sql;
		}
	}

	#### ORDER #################################################################
	// A quick method for appending ORDER conditions
	function order($condition, $direction = 'ASC') {
		if ($condition) {
			$sql = ' ORDER BY '.$condition.' '.$direction;
			$this->sql .= $sql;
			return $sql;
		}
	}

	#### EXTRA #################################################################
	// A quick method for adding extra custom parts into an SQL query
	function extra($condition) {
		if ($condition) {
			$this->sql .= ' '.$condition.' ';
			return $sql;
		}
	}

	#### COUNT #################################################################
	// A quick method for counting table rows
	function count($table, $field = NULL) {
		if (!$field) $field = '*';
		$sql = "SELECT COUNT(".$field.") FROM ".$table;
		$this->sql .= $sql;
		return $sql;
	}

	#### GET ERROR NUMBER ######################################################
	function getErrorNumber() {
		return mysql_errno($this->last_connection);
	}

	#### GET ERROR MESSAGE #####################################################
	function getErrorMessage() {
		return mysql_error($this->last_connection);
	}

	#### DELETE CACHE ##########################################################
	function deleteCache($name) {
		$this->load->helper('cache');
		return delete_cache($name);
	}

}

?>
